/**************************************************************************
Step 1. Include necessary header files such that the stuff your test logic needs is declared. 
Don't forget gtest.h, which declares the testing framework.                                                   
**************************************************************************/
#include "gtest/gtest.h"
#include "include/pf_tree.h"
#include "include/pf_errno.h"
#include "include/pf_internal.h"

#ifdef __cplusplus
extern "C" 
{
#endif
#define RBC_RED   0  /* rb tree color red, refer to pf_tree.c::rbcRed */ 
#define RBC_BLACK 1  /* rb tree color black, refer to pf_tre.c::rbcBlack */

extern int test_get_color(struct pf_tree_node* node);

extern struct pf_tree_node* test_get_parent(struct pf_tree_node* node);

extern struct pf_tree_node* test_get_left(struct pf_tree_node* node);

extern struct pf_tree_node* test_get_right(struct pf_tree_node* node);

#ifdef __cplusplus
}
#endif

typedef struct tree_node_info
{
    const char* node_val;
    const char* parent_val;
    const char* left_val;
    const char* right_val;
    int         node_color;
} tree_node_info_t;

typedef struct tree_node_map
{
    tree_node_info_t nodes_info[128];
    int search_idx;
} tree_node_map_t;

/**************************************************************************
Step 2. Use test fixture to design your complex cases. 
You can add SetUp() to initialize the test data and 
TearDown() to clear the test data for common usage
Pls remember that when you using test fixture, need to use macro "TEST_F" instead of "TEST"                                                 
**************************************************************************/
class PfTreeTest : public testing::Test 
{
    /* This SetUp() will be called before every TEST CASE which is marked by macro "TEST_F" */
    virtual void SetUp() 
    {

    }

    /* This TearDown will be called after every TEST CASE which is marked by macro "TEST_F" */
    virtual void TearDown() 
    {

    }

};

static int normal_cmp(const void* p, const void* q)
{
    return strcmp((const char*)p, (const char*)q);
}

static int empty_cmp(const void* p, const void* q)
{
    EXPECT_NE(0, 0);
    return strcmp((const char*)p, (const char*)q);
}

static int32_t build_tree(pf_tree_t *tree, void **values)
{
    int      ret      = 0;
    assert(tree);
    assert(values);

    while (*values)
    {
        if((ret = pf_tree_insert(tree, *values)) != 0)
        {
            return ret;
        }
        values++;
    }

    return 0;
}

static int32_t check_value(void *arg, pf_tree_node_t *node)
{
    char **vals = NULL;
    int    forw = 1;
    char  *other= NULL;
    vals = (char**)arg;

    assert(arg);
    assert(node);

    if (strcmp(vals[0], "F"))
    {
        forw = -1;
    }

    other = (char*)pf_tree_get_value(node);

    if (!vals[1])
    {
        vals[1] = other;
        return 0;
    }

    if (strcmp(other, vals[1]) == forw)
    {
        vals[1] = other;
        return 0;
    }

    vals[2] = other;

    return 1;
}

static int32_t cb_check_node(void *arg, pf_tree_node_t *node)
{
    tree_node_map_t*  node_map    = NULL;
    tree_node_info_t* node_info   = NULL;
    pf_tree_node_t*   node_parent = NULL;
    pf_tree_node_t*   node_left   = NULL;
    pf_tree_node_t*   node_right  = NULL;
    char*             node_val    = NULL;
    char*             parent_val  = NULL;
    char*             left_val    = NULL;
    char*             right_val   = NULL;
    int               node_color  = -1;

    //ASSERT_NE((void*)NULL, arg);
    //ASSERT_NE(NULL, node);

    node_map = (tree_node_map_t*)arg;
    if(node_map->search_idx < 0 || node_map->search_idx >= (int)PF_ARR_SIZE(node_map->nodes_info))
    {
        return -10;
    }
    node_info = node_map->nodes_info + node_map->search_idx;

    /* get node info */
    node_val = (char*)pf_tree_get_value(node);

    node_parent = test_get_parent(node);
    if(node_parent != NULL)
    {
        parent_val = (char*)pf_tree_get_value(node_parent);
    }

    node_left   = test_get_left(node);
    if(node_left != NULL)
    {
        left_val = (char*)pf_tree_get_value(node_left);
    }

    node_right  = test_get_right(node);
    if(node_right != NULL)
    {
        right_val = (char*)pf_tree_get_value(node_right);
    }

    node_color = test_get_color(node);

    /* check node info */
    if(node_info->node_val == NULL || node_val == NULL || strcmp(node_info->node_val, node_val) != 0)
    {
        /* node value not match */
        return -1;
    }


    if(node_info->parent_val != NULL && parent_val != NULL && strcmp(node_info->parent_val, parent_val) == 0)
    {
        // do nothing.
    }
    else if(node_info->parent_val == NULL && parent_val == NULL)
    {
        // do nothing.
    }
    else /* node parent value not match */
    {
        return -2;
    }

    if(node_info->left_val != NULL && left_val != NULL && strcmp(node_info->left_val, left_val) == 0)
    {
        // do nothing.
    }
    else if(node_info->left_val == NULL && left_val == NULL)
    {
        // do nothing.
    }
    else /* node left value not match */
    {
        return -3;
    }

    if(node_info->right_val != NULL && right_val != NULL && strcmp(node_info->right_val, right_val) == 0)
    {
        // do nothing.
    }
    else if(node_info->right_val == NULL && right_val == NULL)
    {
        // do nothing.
    }
    else /* node right value not match */
    {
        return -4;
    }

    if(node_info->node_color != node_color) /* node color not match */
    {
        return -5;
    }

    node_map->search_idx++;
    return 0;
}

static int32_t cb_err(void* arg, pf_tree_node_t* node)
{
    char* node_val = NULL;
    char* err_val  = NULL;

    assert(arg);
    assert(node);

    err_val = (char*)arg;
    node_val = (char*)pf_tree_get_value(node);

    if(err_val != NULL && node_val != NULL && strcmp(err_val, node_val) == 0)
    {
        return -1;
    }
    else
    {
        return 0;
    }

    return 0;
}

/***************************************************************************
Step 3. Use macro "TEST_F" to start your test case                                      
You can design your test case as the example
***************************************************************************/
TEST_F(PfTreeTest, EmptyTreeTest)
{
    /* Define the local variables */
    pf_tree_t      *tree     = NULL;
    pf_tree_node_t *node     = NULL;
    char           *value    = "foo";
    uint32_t       count     = 0;
    int32_t        ret       = 0;

    tree = pf_tree_create(empty_cmp);
    EXPECT_NE((void*)NULL, tree);

    node = pf_tree_head(tree);
    EXPECT_EQ((void*)NULL, node);

    node = pf_tree_tail(tree);
    EXPECT_EQ((void*)NULL, node);

    node = pf_tree_find_less(tree, value, 1);
    EXPECT_EQ((void*)NULL, node);

    node = pf_tree_find(tree, value);
    EXPECT_EQ((void*)NULL, node);

    count = pf_tree_count(tree);
    EXPECT_EQ((uint32_t)0, count);

    ret = pf_tree_for_each(tree, 0, NULL, check_value);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 1, NULL, check_value);
    EXPECT_EQ(0, ret);

    ret = pf_tree_clear(tree);
    EXPECT_EQ(0, ret);

    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, OneNodeTreeTest)
{
    /* Define the local variables */
    pf_tree_t      *tree  = NULL;
    pf_tree_node_t *node  = NULL;
    char           *value = "hello, world";
    char           *bigger= "hello, world\n";
    char           *less  = "hello, worlc\n";
    char           *other = bigger;
    char           *object= NULL;
    uint32_t       count  = 0;
    int            color  = -1;
    int32_t        ret    = 0;

    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret  = pf_tree_insert(tree, value);
    EXPECT_EQ(0, ret);

    count = pf_tree_count(tree);
    EXPECT_EQ((uint32_t)1, count);

    node = pf_tree_head(tree);
    EXPECT_NE((void*)NULL, node);
    object = (char*)pf_tree_get_value(node);
    EXPECT_STREQ(value, object);
    color = test_get_color(node);
    EXPECT_EQ(RBC_BLACK, color);

    node = pf_tree_tail(tree);
    EXPECT_NE((void*)NULL, node);
    object = (char*)pf_tree_get_value(node);
    EXPECT_STREQ(value, object);

    node = pf_tree_next(node);
    EXPECT_EQ((void*)NULL, node);

    node = pf_tree_head(tree);
    node = pf_tree_prev(node);
    EXPECT_EQ((void*)NULL, node);

    node = pf_tree_find(tree, other);
    EXPECT_EQ((void*)NULL, node);

    node = pf_tree_find(tree, value);
    EXPECT_NE((void*)NULL, node);
    object = (char*)pf_tree_get_value(node);
    EXPECT_STREQ(value, object);

    node = pf_tree_find_less(tree, value, 0);
    EXPECT_EQ((void*)NULL, node);

    node = pf_tree_find_less(tree, value, 1);
    EXPECT_NE((void*)NULL, node);
    object = (char*)pf_tree_get_value(node);
    EXPECT_STREQ(value, object);

    node = pf_tree_find_less(tree, bigger, 0);
    EXPECT_NE((void*)NULL, node);
    object = (char*)pf_tree_get_value(node);
    EXPECT_STREQ(value, object);

    node = pf_tree_find_less(tree, bigger, 1);
    EXPECT_NE((void*)NULL, node);

    object = (char*)pf_tree_get_value(node);
    EXPECT_STREQ(value, object);

    node = pf_tree_find_less(tree, less, 0);
    EXPECT_EQ((void*)NULL, node);

    node = pf_tree_find_less(tree, less, 1);
    EXPECT_EQ((void*)NULL, node);

    count = pf_tree_count(tree);
    EXPECT_EQ((uint32_t)1, count);

    ret = pf_tree_erase_value(tree, value);
    EXPECT_EQ(0, ret);

    count = pf_tree_count(tree);
    EXPECT_EQ((uint32_t)0, count);

    node = pf_tree_find(tree, value);
    EXPECT_EQ((void*)NULL, node);

    ret  = pf_tree_insert(tree, value);
    EXPECT_EQ(0, ret);

    node = pf_tree_head(tree);
    EXPECT_NE((void*)NULL, node);

    object = (char*)pf_tree_erase(tree, node);
    EXPECT_NE((void*)NULL, object);

    count = pf_tree_count(tree);
    EXPECT_EQ((uint32_t)0, count);

    ret = pf_tree_clear(tree);
    EXPECT_EQ(0, ret);

    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, TreeInsertTest)
{
    /* Define the local variables */
    pf_tree_t      *tree      = NULL;
    char           *values[]  = {"hello", "world", "abioy", "!", NULL};
    int32_t        ret        = 0;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    /* Call your function for test */
    /* Check the result */
    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* insert duplicate key */
    ret = pf_tree_insert(tree, values[2]);
    EXPECT_EQ(PF_EKEYREJECTED, ret); 
    /* Clear the test data for this case */
    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, TreeInsertFixupTest)
{
    /* Define the local variables */
    pf_tree_t      *tree      = NULL;
    char           *values[]  = {"40", "30", "50", "20", "35", "33", "38", NULL};
    int32_t        ret        = 0;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    ret = pf_tree_insert(tree, (void*)"37");
    EXPECT_EQ(0, ret);
    EXPECT_EQ((uint32_t)8, pf_tree_count(tree));

    /* Clear the test data for this case */
    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, TreeCountTest)
{
    /* Define the local variables */
    pf_tree_t      *tree      = NULL;
    char           *values[]  = {"hello", "world", "abioy", "!", NULL};
    int32_t        ret        = 0;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    EXPECT_EQ((uint32_t)4, pf_tree_count(tree));

    /* Clear the test data for this case */
    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, TreeHeadTailTest)
{
    /* Define the local variables */
    pf_tree_t      *tree      = NULL;
    char           *values[]  = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL};
    int32_t        ret        = 0;
    pf_tree_node_t *node      = NULL;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    node = pf_tree_head(tree);
    EXPECT_STREQ("0", (char*)pf_tree_get_value(node));

    node = pf_tree_tail(tree);
    EXPECT_STREQ("9", (char*)pf_tree_get_value(node));

    /* Clear the test data for this case */
    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, TreeFindTest)
{
    /* Define the local variables */
    pf_tree_t      *tree      = NULL;
    char           *values[]  = {"hello", "world", "abioy", "!", NULL};
    int32_t        ret        = 0;
    pf_tree_node_t *node      = NULL;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    node = pf_tree_find(tree, (void*)values[1]);
    EXPECT_STREQ(values[1], (char*)pf_tree_get_value(node));

    /* Clear the test data for this case */
    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, TreeFindLessTest)
{
    /* Define the local variables */
    pf_tree_t      *tree      = NULL;
    char           *values[]  = {"a3", "hello", "a1", "world", "a2", "abioy", "a0", "!", "a4", NULL};
    int32_t        ret        = 0;
    pf_tree_node_t *node      = NULL;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    node = pf_tree_find_less(tree, (void*)values[4], 0);
    EXPECT_STREQ(values[2], (char*)pf_tree_get_value(node));

    /* Clear the test data for this case */
    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, TreePrevTest)
{
    /* Define the local variables */
    pf_tree_t      *tree      = NULL;
    char           *values[]  = {"1", "3", "2", "4", "7", "6", "5", "8", "a", "9", "b", "c", "d", "e", "f", "g", "h", "i", NULL};
    int32_t        ret        = 0;
    pf_tree_node_t *node      = NULL;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    node = pf_tree_head(tree);
    EXPECT_NE((void*)NULL, (void*)node);

    node = pf_tree_prev(node);
    EXPECT_EQ((void*)NULL, (void*)node);

    node = pf_tree_find(tree, (void*)"9");
    EXPECT_NE((void*)NULL, (void*)node);

    node = pf_tree_prev(node);
    EXPECT_NE((void*)NULL, (void*)node);
    EXPECT_STREQ("8", (char*)pf_tree_get_value(node));

    node = pf_tree_find(tree, (void*)"8");
    EXPECT_NE((void*)NULL, (void*)node);

    node = pf_tree_prev(node);
    EXPECT_NE((void*)NULL, (void*)node);
    EXPECT_STREQ("7", (char*)pf_tree_get_value(node));

    /* Clear the test data for this case */
    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, TreeNextTest)
{
    /* Define the local variables */
    pf_tree_t      *tree      = NULL;
    char           *values[]  = {"1", "3", "2", "4", "7", "6", "5", "8", "a", "9", "b", "c", "d", "e", "f", "g", "h", "i", NULL};
    int32_t        ret        = 0;
    pf_tree_node_t *node      = NULL;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    node = pf_tree_tail(tree);
    EXPECT_NE((void*)NULL, (void*)node);

    node = pf_tree_next(node);
    EXPECT_EQ((void*)NULL, (void*)node);

    node = pf_tree_find(tree, (void*)"7");
    EXPECT_NE((void*)NULL, (void*)node);

    node = pf_tree_next(node);
    EXPECT_NE((void*)NULL, (void*)node);
    EXPECT_STREQ("8", (char*)pf_tree_get_value(node));

    node = pf_tree_find(tree, (void*)"8");
    EXPECT_NE((void*)NULL, (void*)node);

    node = pf_tree_next(node);
    EXPECT_NE((void*)NULL, (void*)node);
    EXPECT_STREQ("9", (char*)pf_tree_get_value(node));

    /* Clear the test data for this case */
    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, TreeForEachTest)
{
    /* Define the local variables */
    pf_tree_t      *tree      = NULL;
    char           *values[]  = {"1", "3", "2", "4", "7", "6", "5", "8", "a", "9", "b", "c", "d", "e", "f", "g", "h", "i", NULL};
    int32_t        ret        = 0;
    char           *args[]    = {"F", NULL, NULL};

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    ret = pf_tree_for_each(tree, 1, args, check_value);
    EXPECT_EQ(0, ret) << "l:'" << args[1] << "'\tr:'" << args[2] << "'";

    args[0] = "B";
    args[1] = NULL;
    ret = pf_tree_for_each(tree, 0, args, check_value);
    EXPECT_EQ(0, ret) << "l:'" << args[1] << "'\tr:'" << args[2] << "'";

    /* test case for error callback function */
    ret = pf_tree_for_each(tree, 0, (void*)"2", cb_err);
    EXPECT_EQ(-1, ret);

    ret = pf_tree_for_each(tree, 0, (void*)"b", cb_err);
    EXPECT_EQ(-1, ret);

    ret = pf_tree_for_each(tree, 0, (void*)"g", cb_err);
    EXPECT_EQ(-1, ret);
    
    ret = pf_tree_for_each(tree, 1, (void*)"2", cb_err);
    EXPECT_EQ(-1, ret);

    ret = pf_tree_for_each(tree, 1, (void*)"8", cb_err);
    EXPECT_EQ(-1, ret);

    ret = pf_tree_for_each(tree, 1, (void*)"e", cb_err);
    EXPECT_EQ(-1, ret);

    /* Clear the test data for this case */
    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}


TEST_F(PfTreeTest, TreeEraseValueTest)
{
    /* Define the local variables */
    pf_tree_t      *tree      = NULL;
    char           *values[]  = {"hello", "world", "abioy", "!", NULL};
    uint32_t       count      = 0;
    int32_t        ret        = 0;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    count = pf_tree_count(tree);
    EXPECT_EQ((uint32_t)4, count);

    ret = pf_tree_erase_value(tree, (void*)values[2]);
    EXPECT_EQ(0, ret);

    count = pf_tree_count(tree);
    EXPECT_EQ((uint32_t)3, count);

    /* erase same value again */
    ret = pf_tree_erase_value(tree, (void*)values[2]);
    EXPECT_EQ(PF_ENODATA, ret);

    count = pf_tree_count(tree);
    EXPECT_EQ((uint32_t)3, count);

    ret = pf_tree_erase_value(tree, (void*)values[0]);
    EXPECT_EQ(0, ret);

    count = pf_tree_count(tree);
    EXPECT_EQ((uint32_t)2, count);

    ret = pf_tree_erase_value(tree, (void*)values[1]);
    EXPECT_EQ(0, ret);

    count = pf_tree_count(tree);
    EXPECT_EQ((uint32_t)1, count);

    ret = pf_tree_erase_value(tree, (void*)values[3]);
    EXPECT_EQ(0, ret);

    count = pf_tree_count(tree);
    EXPECT_EQ((uint32_t)0, count);

    ret = pf_tree_erase_value(tree, (void*)"");
    EXPECT_EQ(PF_ENODATA, ret);

    /* Clear the test data for this case */
    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, TreeEraseTest)
{
    /* Define the local variables */
    pf_tree_t      *tree      = NULL;
    char           *values[]  = {"hello", "world", "abioy", "!", NULL};
    int32_t        ret        = 0;
    pf_tree_node_t *node      = NULL;
    char*          val        = NULL;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    node = pf_tree_find(tree, (void*)values[1]);
    EXPECT_NE((void*)NULL, node);
    val = (char *)pf_tree_erase(tree, node);
    EXPECT_STREQ(values[1], val);

    /* Clear the test data for this case */
    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

#if 0  /* Should not test this case. Caller should make sure not happen it. */
TEST_F(PfTreeTest, TreeEraseIllegalNodeTest)
{
    /* Define the local variables */
    pf_tree_t      *tree      = NULL;
    pf_tree_t      *tree2     = NULL;
    char           *values[]  = {"hello", NULL};
    int32_t        ret        = 0;
    pf_tree_node_t *node      = NULL;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    build_tree(tree, (void**)values);
    tree2 = pf_tree_create(normal_cmp);
    build_tree(tree2, (void**)values);

    /* Call your function for test */
    /* Check the result */
    node = pf_tree_find(tree, (void*)values[0]);
    EXPECT_EQ((void*)NULL, pf_tree_erase(tree2, node));
    EXPECT_EQ((uint32_t)1, pf_tree_count(tree));
    EXPECT_EQ((uint32_t)1, pf_tree_count(tree2));

    /* Clear the test data for this case */
    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}
#endif


TEST_F(PfTreeTest, TreeEraseChildTest)
{
    /* Define the local variables */
    pf_tree_t      *tree      = NULL;
    char           *values[]  = {"40", "50", "30", "20", "35", "38", NULL};
    int32_t        ret        = 0;
    pf_tree_node_t *node      = NULL;
    char*          val        = NULL;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    node = pf_tree_find(tree, (void*)"30");
    EXPECT_NE((void*)NULL, node);
    val = (char *)pf_tree_erase(tree, node);
    EXPECT_STREQ("30", val);

    node = pf_tree_find(tree, (void*)"38");
    EXPECT_NE((void*)NULL, node);
    val = (char *)pf_tree_erase(tree, node);
    EXPECT_STREQ("38", val);

    /* Clear the test data for this case */
    ret = pf_tree_clear(tree);
    EXPECT_EQ(0, ret);

    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}


TEST_F(PfTreeTest, TreeEraseFixupTest1)
{
    /* Define the local variables */
    pf_tree_t  *tree          = NULL;
    char      *values[]       = {"1", "3", "2", "4", "7", "6", "5", "8", "a", "0", "9", "b", "c", "40", "30", "50", "20", "35", "33", "38", NULL};
    int32_t        ret        = 0;
    uint32_t  expected_count  = 20;
    char      **value         = NULL;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    value = values; 
    while (*value)
    {
        ret = pf_tree_erase_value(tree, (void*)*value);
        EXPECT_EQ(0, ret);

        expected_count--;
        EXPECT_EQ(expected_count, pf_tree_count(tree));

        value++;
    }

    /* Clear the test data for this case */
    ret = pf_tree_clear(tree);
    EXPECT_EQ(0, ret);

    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}


TEST_F(PfTreeTest, TreeEraseFixupTest2)
{
    /* Define the local variables */
    pf_tree_t *tree          = NULL;
    char      *values[]      = {"1", "3", "2", "4", "7", "6", "5", "8", "a", "9", "b", "c", "d", "e", "f", "g", "h", "i", NULL};
    int32_t   ret            = 0;
    uint32_t  expected_count = 18;
    char      **value        = NULL;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    value = values; 
    while (*value)
    {
        ret = pf_tree_erase_value(tree, (void*)*value);
        EXPECT_EQ(0, ret);

        expected_count--;
        EXPECT_EQ(expected_count, pf_tree_count(tree));

        value++;
    }

    /* Clear the test data for this case */
    ret = pf_tree_clear(tree);
    EXPECT_EQ(0, ret);

    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, TreeEraseFixupTest3)
{
    /* Define the local variables */
    pf_tree_t *tree          = NULL;
    char      *values[]      = {"1", "3", "2", "4", "7", "6", "5", "8", "a", "9", "b", "c", "d", "e", "f", "g", "h", "i", "j", NULL};
    int32_t   ret            = 0;
    uint32_t  expected_count = 19;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    ret = pf_tree_erase_value(tree, (void*)"j");
    EXPECT_EQ(0, ret);

    expected_count--;
    EXPECT_EQ(expected_count, pf_tree_count(tree));

    ret = pf_tree_erase_value(tree, (void*)"i");
    EXPECT_EQ(0, ret);

    expected_count--;
    EXPECT_EQ(expected_count, pf_tree_count(tree));

    ret = pf_tree_erase_value(tree, (void*)"h");
    EXPECT_EQ(0, ret);

    expected_count--;
    EXPECT_EQ(expected_count, pf_tree_count(tree));

    ret = pf_tree_erase_value(tree, (void*)"g");
    EXPECT_EQ(0, ret);

    expected_count--;
    EXPECT_EQ(expected_count, pf_tree_count(tree));

    /* Clear the test data for this case */
    ret = pf_tree_clear(tree);
    EXPECT_EQ(0, ret);

    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, TreeEraseFixupTest4)
{
    /* Define the local variables */
    pf_tree_t *tree          = NULL;
    char      *values[]      = {"1", "3", "2", "4", "7", "6", "5", "8", "a", "9", "b", "c", "d", "e", "f", "g", "h", "i", "j", NULL};
    int32_t   ret            = 0;
    uint32_t  expected_count = 19;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    ret = pf_tree_erase_value(tree, (void*)"i");
    EXPECT_EQ(0, ret);

    expected_count--;
    EXPECT_EQ(expected_count, pf_tree_count(tree));

    ret = pf_tree_erase_value(tree, (void*)"j");
    EXPECT_EQ(0, ret);

    expected_count--;
    EXPECT_EQ(expected_count, pf_tree_count(tree));

    ret = pf_tree_erase_value(tree, (void*)"g");
    EXPECT_EQ(0, ret);
    expected_count--;
    EXPECT_EQ(expected_count, pf_tree_count(tree));

    ret = pf_tree_erase_value(tree, (void*)"h");
    EXPECT_EQ(0, ret);
    expected_count--;
    EXPECT_EQ(expected_count, pf_tree_count(tree));

    /* Clear the test data for this case */
    ret = pf_tree_clear(tree);
    EXPECT_EQ(0, ret);

    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, TreeEraseFixupTest5)
{
    /* Define the local variables */
    pf_tree_t *tree          = NULL;
    char      *values[]      = {"1", "3", "2", "4", "7", "6", "5", "8", "a", "9", "b", "c", "d", "e", "f", "g", "h", "i", NULL};
    int32_t   ret            = 0;
    uint32_t  expected_count = 18;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    ret = pf_tree_erase_value(tree, (void*)"h");
    EXPECT_EQ(0, ret);

    expected_count--;
    EXPECT_EQ(expected_count, pf_tree_count(tree));

    ret = pf_tree_erase_value(tree, (void*)"c");
    EXPECT_EQ(0, ret);

    expected_count--;
    EXPECT_EQ(expected_count, pf_tree_count(tree));

    /* Clear the test data for this case */
    ret = pf_tree_clear(tree);
    EXPECT_EQ(0, ret);

    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, TreeEraseFixupTest6)
{
    /* Define the local variables */
    pf_tree_t *tree          = NULL;
    char      *values[]      = {"9", "5", "i", "3", "7", "6", "8", "4", NULL};
    int32_t   ret            = 0;
    uint32_t  expected_count = 8;

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    ret = build_tree(tree, (void**)values);
    EXPECT_EQ(0,ret); 

    /* Call your function for test */
    /* Check the result */
    ret = pf_tree_erase_value(tree, (void*)"3");
    EXPECT_EQ(0, ret);

    expected_count--;
    EXPECT_EQ(expected_count, pf_tree_count(tree));

    /* Clear the test data for this case */
    ret = pf_tree_clear(tree);
    EXPECT_EQ(0, ret);

    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}

TEST_F(PfTreeTest, TreeInsertEraseFullTest)
{
    /* Define the local variables */
    int32_t   ret            = 0;
    uint32_t  count          = 0;
    pf_tree_t *tree          = NULL;
    char      *values[]      = {"309", "103", "034", "439", 
                                "800", "231", "291", "134", 
                                "198", "046", "227", "201", 
                                "685", "386"};
    tree_node_map_t node_map_f_1 = 
        {
            {
                {"309", NULL,  NULL,  NULL,  RBC_BLACK}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };
    tree_node_map_t node_map_b_2 = 
        {
            {
                {"309", NULL,  "103", NULL,  RBC_BLACK}, 
                {"103", "309", NULL,  NULL,  RBC_RED}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };
    tree_node_map_t node_map_f_3 = 
        {
            {
                {"034", "103", NULL,  NULL,  RBC_RED}, 
                {"103", NULL , "034", "309", RBC_BLACK}, 
                {"309", "103", NULL,  NULL,  RBC_RED}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };
    tree_node_map_t node_map_b_4 = 
        {
            {
                {"439", "309", NULL,  NULL,  RBC_RED}, 
                {"309", "103", NULL,  "439", RBC_BLACK}, 
                {"103", NULL , "034", "309", RBC_BLACK}, 
                {"034", "103", NULL,  NULL,  RBC_BLACK}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };
    tree_node_map_t node_map_f_5 = 
        {
            {
                {"034", "103", NULL,  NULL,  RBC_BLACK}, 
                {"103", NULL , "034", "439", RBC_BLACK}, 
                {"309", "439", NULL,  NULL,  RBC_RED}, 
                {"439", "103", "309", "800", RBC_BLACK}, 
                {"800", "439", NULL,  NULL,  RBC_RED}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };
    tree_node_map_t node_map_b_6 = 
        {
            {
                {"800", "439", NULL,  NULL,  RBC_BLACK}, 
                {"439", "103", "309", "800", RBC_RED}, 
                {"309", "439", "231", NULL,  RBC_BLACK}, 
                {"231", "309", NULL,  NULL,  RBC_RED}, 
                {"103", NULL , "034", "439", RBC_BLACK}, 
                {"034", "103", NULL,  NULL,  RBC_BLACK}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };
    tree_node_map_t node_map_f_7 = 
        {
            {
                {"034", "103", NULL,  NULL,  RBC_BLACK}, 
                {"103", NULL , "034", "439", RBC_BLACK}, 
                {"231", "291", NULL,  NULL,  RBC_RED}, 
                {"291", "439", "231", "309", RBC_BLACK}, 
                {"309", "291", NULL,  NULL,  RBC_RED}, 
                {"439", "103", "291", "800", RBC_RED}, 
                {"800", "439", NULL,  NULL,  RBC_BLACK}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };
    tree_node_map_t node_map_b_8 = 
        {
            {
                {"800", "439", NULL,  NULL,  RBC_BLACK}, 
                {"439", "291", "309", "800", RBC_RED}, 
                {"309", "439", NULL,  NULL,  RBC_BLACK}, 
                {"291", NULL,  "103", "439", RBC_BLACK}, 
                {"231", "103", "134", NULL,  RBC_BLACK}, 
                {"134", "231", NULL,  NULL,  RBC_RED}, 
                {"103", "291", "034", "231", RBC_RED}, 
                {"034", "103", NULL,  NULL,  RBC_BLACK}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };
    tree_node_map_t node_map_f_9 = 
        {
            {
                {"034", "103", NULL,  NULL,  RBC_BLACK}, 
                {"103", "291", "034", "198", RBC_RED}, 
                {"134", "198", NULL,  NULL,  RBC_RED}, 
                {"198", "103", "134", "231", RBC_BLACK}, 
                {"231", "198", NULL,  NULL,  RBC_RED}, 
                {"291", NULL,  "103", "439", RBC_BLACK}, 
                {"309", "439", NULL,  NULL,  RBC_BLACK}, 
                {"439", "291", "309", "800", RBC_RED}, 
                {"800", "439", NULL,  NULL,  RBC_BLACK}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };
    tree_node_map_t node_map_b_10 = 
        {
            {
                {"800", "439", NULL,  NULL,  RBC_BLACK}, 
                {"439", "291", "309", "800", RBC_RED}, 
                {"309", "439", NULL,  NULL,  RBC_BLACK}, 
                {"291", NULL,  "103", "439", RBC_BLACK}, 
                {"231", "198", NULL,  NULL,  RBC_RED}, 
                {"198", "103", "134", "231", RBC_BLACK}, 
                {"134", "198", NULL,  NULL,  RBC_RED}, 
                {"103", "291", "034", "198", RBC_RED}, 
                {"046", "034", NULL,  NULL,  RBC_RED}, 
                {"034", "103", NULL,  "046", RBC_BLACK}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };
    tree_node_map_t node_map_f_11 = 
        {
            {
                {"034", "103", NULL,  "046", RBC_BLACK}, 
                {"046", "034", NULL,  NULL,  RBC_RED}, 
                {"103", "291", "034", "198", RBC_BLACK}, 
                {"134", "198", NULL,  NULL,  RBC_BLACK}, 
                {"198", "103", "134", "231", RBC_RED}, 
                {"227", "231", NULL,  NULL,  RBC_RED}, 
                {"231", "198", "227", NULL,  RBC_BLACK}, 
                {"291", NULL,  "103", "439", RBC_BLACK}, 
                {"309", "439", NULL,  NULL,  RBC_BLACK}, 
                {"439", "291", "309", "800", RBC_BLACK}, 
                {"800", "439", NULL,  NULL,  RBC_BLACK}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };
    tree_node_map_t node_map_b_12 = 
        {
            {
                {"800", "439", NULL,  NULL,  RBC_BLACK}, 
                {"439", "291", "309", "800", RBC_BLACK}, 
                {"309", "439", NULL,  NULL,  RBC_BLACK}, 
                {"291", NULL,  "103", "439", RBC_BLACK}, 
                {"231", "227", NULL,  NULL,  RBC_RED}, 
                {"227", "198", "201", "231", RBC_BLACK}, 
                {"201", "227", NULL,  NULL,  RBC_RED}, 
                {"198", "103", "134", "227", RBC_RED}, 
                {"134", "198", NULL,  NULL,  RBC_BLACK}, 
                {"103", "291", "034", "198", RBC_BLACK}, 
                {"046", "034", NULL,  NULL,  RBC_RED}, 
                {"034", "103", NULL,  "046", RBC_BLACK}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };
    tree_node_map_t node_map_f_13 = 
        {
            {
                {"034", "103", NULL,  "046", RBC_BLACK}, 
                {"046", "034", NULL,  NULL,  RBC_RED}, 
                {"103", "291", "034", "198", RBC_BLACK}, 
                {"134", "198", NULL,  NULL,  RBC_BLACK}, 
                {"198", "103", "134", "227", RBC_RED}, 
                {"201", "227", NULL,  NULL,  RBC_RED}, 
                {"227", "198", "201", "231", RBC_BLACK}, 
                {"231", "227", NULL,  NULL,  RBC_RED}, 
                {"291", NULL,  "103", "439", RBC_BLACK}, 
                {"309", "439", NULL,  NULL,  RBC_BLACK}, 
                {"439", "291", "309", "800", RBC_BLACK}, 
                {"685", "800", NULL,  NULL,  RBC_RED}, 
                {"800", "439", "685", NULL,  RBC_BLACK}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };
    tree_node_map_t node_map_b_14 = 
        {
            {
                {"800", "439", "685", NULL,  RBC_BLACK}, 
                {"685", "800", NULL,  NULL,  RBC_RED}, 
                {"439", "291", "309", "800", RBC_BLACK}, 
                {"386", "309", NULL,  NULL,  RBC_RED}, 
                {"309", "439", NULL,  "386", RBC_BLACK}, 
                {"291", NULL,  "103", "439", RBC_BLACK}, 
                {"231", "227", NULL,  NULL,  RBC_RED}, 
                {"227", "198", "201", "231", RBC_BLACK}, 
                {"201", "227", NULL,  NULL,  RBC_RED}, 
                {"198", "103", "134", "227", RBC_RED}, 
                {"134", "198", NULL,  NULL,  RBC_BLACK}, 
                {"103", "291", "034", "198", RBC_BLACK}, 
                {"046", "034", NULL,  NULL,  RBC_RED}, 
                {"034", "103", NULL,  "046", RBC_BLACK}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };
    tree_node_map_t node_map_e_1 = 
        {
            {
                {"034", "103", NULL,  "046", RBC_BLACK}, 
                {"046", "034", NULL,  NULL,  RBC_RED}, 
                {"103", "309", "034", "198", RBC_BLACK}, 
                {"134", "198", NULL,  NULL,  RBC_BLACK}, 
                {"198", "103", "134", "227", RBC_RED}, 
                {"201", "227", NULL,  NULL,  RBC_RED}, 
                {"227", "198", "201", "231", RBC_BLACK}, 
                {"231", "227", NULL,  NULL,  RBC_RED}, 
                {"309", NULL,  "103", "439", RBC_BLACK}, 
                {"386", "439", NULL,  NULL,  RBC_BLACK}, 
                {"439", "309", "386", "800", RBC_BLACK}, 
                {"685", "800", NULL,  NULL,  RBC_RED}, 
                {"800", "439", "685", NULL,  RBC_BLACK}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };
    tree_node_map_t node_map_e_2 = 
        {
            {
                {"034", "103", NULL,  "046", RBC_BLACK}, 
                {"046", "034", NULL,  NULL,  RBC_RED}, 
                {"103", "309", "034", "198", RBC_BLACK}, 
                {"134", "198", NULL,  NULL,  RBC_BLACK}, 
                {"198", "103", "134", "227", RBC_RED}, 
                {"201", "227", NULL,  NULL,  RBC_RED}, 
                {"227", "198", "201", "231", RBC_BLACK}, 
                {"231", "227", NULL,  NULL,  RBC_RED}, 
                {"309", NULL,  "103", "685", RBC_BLACK}, 
                {"439", "685", NULL,  NULL,  RBC_BLACK}, 
                {"685", "309", "439", "800", RBC_BLACK}, 
                {"800", "685", NULL,  NULL,  RBC_BLACK}, 
                {NULL,  NULL,  NULL,  NULL,  -1}, 
            }, 
            0
        };

    /* initilize test data for this case */
    tree = pf_tree_create(normal_cmp);
    EXPECT_NE((void*)NULL, tree);

    /* Call your function for test */
    /* Check the result */
    /* insert 1 */
    ret = pf_tree_insert(tree, values[0]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 1, &node_map_f_1, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_f_1.search_idx);

    /* insert 2 */
    ret = pf_tree_insert(tree, values[1]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 0, &node_map_b_2, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_b_2.search_idx);

    /* insert 3 */
    ret = pf_tree_insert(tree, values[2]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 1, &node_map_f_3, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_f_3.search_idx);

    /* insert 4 */
    ret = pf_tree_insert(tree, values[3]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 0, &node_map_b_4, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_b_4.search_idx);

    /* insert 5 */
    ret = pf_tree_insert(tree, values[4]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 1, &node_map_f_5, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_f_5.search_idx);

    /* insert 6 */
    ret = pf_tree_insert(tree, values[5]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 0, &node_map_b_6, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_b_6.search_idx);

    /* insert 7 */
    ret = pf_tree_insert(tree, values[6]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 1, &node_map_f_7, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_f_7.search_idx);

    /* insert 8 */
    ret = pf_tree_insert(tree, values[7]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 0, &node_map_b_8, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_b_8.search_idx);

    /* insert 9 */
    ret = pf_tree_insert(tree, values[8]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 1, &node_map_f_9, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_f_9.search_idx);

    /* insert 10 */
    ret = pf_tree_insert(tree, values[9]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 0, &node_map_b_10, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_b_10.search_idx);

    /* insert 11 */
    ret = pf_tree_insert(tree, values[10]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 1, &node_map_f_11, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_f_11.search_idx);

    /* insert 12 */
    ret = pf_tree_insert(tree, values[11]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 0, &node_map_b_12, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_b_12.search_idx);

    /* insert 13 */
    ret = pf_tree_insert(tree, values[12]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 1, &node_map_f_13, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_f_13.search_idx);

    /* insert 14 */
    ret = pf_tree_insert(tree, values[13]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 0, &node_map_b_14, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_b_14.search_idx);

    /* erase 1 ("309") */
    ret = pf_tree_erase_value(tree, values[6]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 1, &node_map_e_1, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_e_1.search_idx);

    /* erase 2 ("386") */
    ret = pf_tree_erase_value(tree, values[13]);
    EXPECT_EQ(0, ret);

    ret = pf_tree_for_each(tree, 1, &node_map_e_2, cb_check_node);
    EXPECT_EQ(0, ret);
    count = pf_tree_count(tree);
    EXPECT_EQ(count, (uint32_t)node_map_e_2.search_idx);


    /* Clear the test data for this case */
    ret = pf_tree_clear(tree);
    EXPECT_EQ(0, ret);

    ret = pf_tree_destory(tree);
    EXPECT_EQ(0, ret);
}
